package inutan.game.service;

import bright.serialization.ByteBuf;
import inutan.common.constant.DataConstant;
import inutan.common.context.FlowContext;
import inutan.common.message.ActionErrorEnum;
import inutan.common.utils.HttpUtils;
import inutan.data.Role.RoleInitialCfgVal;
import inutan.game.business.GameFlowContext;
import inutan.game.context.GameUserContext;
import inutan.game.entity.UserInfo;
import inutan.game.entity.prop.BaseItemInfo;
import inutan.game.proto.UserProto;
import inutan.game.storage.StorageContext;
import luban.common.Command;
import luban.common.LongValue;
import luban.user.LoginRequest;
import org.ricks.common.json.JSONObject;
import org.ricks.common.lang.Logger;
import org.ricks.ioc.anno.Autowired;
import org.ricks.ioc.anno.Bean;
import org.ricks.orm.OrmContext;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;


/**
 * @author ：demon-chen
 * 来自业务集群的消息 使用自定义消息体
 * 如果1:1 对应 ，
 */
@Bean
public class UserService {

    @Autowired
    private TaskService taskService;

    /**
     * key=userId  value=玩家生命周期容器容器
     */
    private static final Map<Long, GameUserContext> userContextMap = new ConcurrentHashMap();

    public void login(GameFlowContext context, long userId) {

        //玩家登陆实际 业务逻辑
        Optional<UserInfo> optionalUser = OrmContext.me().uniqueCacheLoad(UserInfo.class, userId);
        context.setUserId(userId);
        GameUserContext userContext = userContextMap.getOrDefault(userId, new GameUserContext(userId));
        context.setGameUserContext(userContext);
        optionalUser.ifPresentOrElse(user -> login(context,user), () -> register(context, userId));
    }

    private void login(GameFlowContext context, UserInfo userInfo) {
        // load 背包数据 任务数据
        GameUserContext userContext = context.getGameUserContext();
        Logger.info(userInfo.getId()+ ": 玩家开始登陆！");
        userContext.init(() -> {
            Logger.info(userInfo.getId()+ ": 玩家初始化数据完成！");
            LongValue value = new LongValue();
            value.value = context.getUserId();
            //推送玩家登录成功
            context.sendResponse(DataConstant.RUTE_MESSAGE, Command.LoginSuccess,value); //通知网关绑定userId
            context.sendResponse(DataConstant.BROADCAST_MESSAGE, Command.Login, UserProto.createRoleInfo(userInfo)); //推送玩家基础信息
            context.sendResponse(DataConstant.BROADCAST_MESSAGE, Command.GetItems); //背包信息
            context.sendResponse(DataConstant.BROADCAST_MESSAGE, Command.GetTasks, taskService.getTaskList(userInfo.getId())); //任务信息
        });
    }

    private void register(GameFlowContext context,long userId) {
        Logger.info(userId+ ": 玩家开始注册！");
        UserInfo saveUserInfo = new UserInfo();
        saveUserInfo.setId(userId);
        saveUserInfo.setUserName("ricks");
        saveUserInfo.setLevel(1);
        saveUserInfo.setGold(10000);
        saveUserInfo.setResourceNum(Map.of(1000,100));
        OrmContext.me().insert(saveUserInfo);

        //初始化任务
//            taskService.initFirstMission(userId);
        //初始化道具
        getInitResource(context);

        System.err.println("user开始注册 userId:" + userId);

//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));
//        context.useProps(List.of(new BaseItemInfo(Type.GOLD, Type.GOLD, 999),new BaseItemInfo(Type.GOLD, Type.GOLD, 999),new BaseItemInfo(Type.GOLD, Type.GOLD, 999)
//        ,new BaseItemInfo(Type.GOLD, Type.GOLD, 999),new BaseItemInfo(Type.GOLD, Type.GOLD, 999),new BaseItemInfo(Type.GOLD, Type.GOLD, 999),new BaseItemInfo(Type.GOLD, Type.GOLD, 999)
//        ,new BaseItemInfo(Type.GOLD, Type.GOLD, 999),new BaseItemInfo(Type.GOLD, Type.GOLD, 999),new BaseItemInfo(Type.GOLD, Type.GOLD, 999),new BaseItemInfo(Type.GOLD, Type.GOLD, 999)));

        // load 背包数据 任务数据
        //推送玩家登录成功
        LongValue value = new LongValue();
        value.value = userId;
        context.sendResponse(DataConstant.RUTE_MESSAGE, Command.LoginSuccess,value); //通知网关绑定userId
        context.sendResponse(DataConstant.BROADCAST_MESSAGE, Command.Login, UserProto.createRoleInfo(saveUserInfo)); //推送玩家基础信息
        context.sendResponse(DataConstant.BROADCAST_MESSAGE, Command.GetItems); //背包信息
        context.sendResponse(DataConstant.BROADCAST_MESSAGE, Command.GetTasks, taskService.getTaskList(userId)); //任务信息
    }

    private void getInitResource(GameFlowContext context){
        List<RoleInitialCfgVal> initItemList = StorageContext.tables().getTbRoleInitialCfg().getDataList();
        List<BaseItemInfo> BaseItemInfos = initItemList.stream().map(x->new BaseItemInfo(x.type,x.id,x.num)).collect(Collectors.toList());
        context.addProps(BaseItemInfos);
    }

    /**
     * 登录校验
     * @param loginRequest
     */
    public long loginValidate(LoginRequest loginRequest) {
        //String verifyUserTokenStr = HttpUtils.doGet(HttpUtils.verifyUserTokenUrl(loginRequest.userToken));
        String loginValidateInfo = HttpUtils.doGet("http://127.0.0.1:8080/loginValidate?userToken="+loginRequest.userToken + "&sign="+ loginRequest.sign);
        JSONObject jsonObject = new JSONObject(loginValidateInfo);
        short code = jsonObject.getShort("msgCode");
        String message = jsonObject.getString("message");
        ActionErrorEnum.validateLogin.assertTrue(code == 0,message);
        return jsonObject.getLong("userId");
    }
}
